package com.simple.mipc.handler;

import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;

import androidx.annotation.NonNull;

import com.google.gson.Gson;
import com.simple.mipc.messager.ExecutorManager;
import com.simple.mipc.messager.MessengerMessage;

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

import lombok.SneakyThrows;

public class MessageHandler extends Handler {

    public static final int REGISTER_CODE = 0;

    public static final int UNREGISTER_CODE = 1;

    public static final int APPLY_FUNCTION_CODE = 2;

    public static final int UNKNOWN_CODE = 3;

    public static final int RESULT_CODE = 4;

    public static final String UNKNOWN_KEY = "unknown_key";

    public static final String MESSAGE_NAME = "message_name";

    public static final String FUNCTION_RES = "function_res";

    public static final String RESULT_DATA = "data";

    public MessageHandler() {
        this(Looper.getMainLooper());
    }

    public MessageHandler(@NonNull Looper looper) {
        super(looper);
    }

    public Gson gson = new Gson();

    @Override
    public void handleMessage(@NonNull Message msg) {
        Bundle bundle = msg.getData();
        int what = bundle.getInt("what");
        switch (what) {
            case REGISTER_CODE:
                MessengerMessage.getInstance().register(bundle.getString(MESSAGE_NAME), msg.replyTo);
                break;
            case UNREGISTER_CODE:
                MessengerMessage.getInstance().unregister(bundle.getString(MESSAGE_NAME));
                break;
            case APPLY_FUNCTION_CODE:
                executeFunction(bundle, msg);
                break;
            default:
                Message obtain = Message.obtain(msg);
                bundle = obtain.getData();
                bundle.putInt("what", UNKNOWN_CODE);
                bundle.putString(UNKNOWN_KEY, String.format("未知的编码：%s", msg.what));
                // 返回数据给调用者，不存在的识别码
                sendMessageToClient(msg.replyTo, obtain);
        }
    }

    @SneakyThrows
    private void executeFunction(Bundle bundle, Message msg) {
        int what = bundle.getInt("what");
        String res = bundle.getString(FUNCTION_RES);
        Object executor = ExecutorManager.getInstance().executor(res, bundle);
        if (Objects.equals(what, RESULT_CODE)) {
            return;
        }
        Map<String, Object> map = new HashMap<>();
        if (executor instanceof String) {
            map.put(RESULT_DATA, executor);
        }
        String json = gson.toJson(map);
        Message obtain = Message.obtain();
        Bundle result = obtain.getData();
        result.putInt("what", RESULT_CODE);
        result.putString(FUNCTION_RES, res);
        result.putString(RESULT_DATA, json);
        msg.replyTo.send(obtain);
    }

    private void sendMessageToClient(Messenger clientMessenger, Message message) {
        try {
            clientMessenger.send(message);
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }
}
